package jp.sourceforge.akjrcp.dropsomething;

import java.io.File;
import java.io.IOException;

import jp.sourceforge.akjrcp.akj_betas.Akj_betasPlugin;
import jp.sourceforge.akjrcp.akj_betas.Messages;
import jp.sourceforge.akjrcp.audio.WavAudioSettingComposite;
import jp.sourceforge.akjrcp.dropsomething.FFMpegConvertTabBuilder.FFMpegConvertTab;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegExecuter;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegOptions;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUI;
import jp.sourceforge.akjrcp.ffmpeg.FFMpegUtils;
import jp.sourceforge.akjrcp.ffmpeg.WavFFMpegPreference;
import jp.sourceforge.akjrcp.ui.DirectryBasedExecuterListener;
import jp.sourceforge.akjrcp.ui.FileOverwriteControler;
import jp.sourceforge.akjrcp.util.StatusBarUtils;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.custom.CTabFolder;
import org.eclipse.swt.custom.CTabItem;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.ExpandBar;
import org.eclipse.swt.widgets.ExpandItem;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.part.ViewPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;

public class WavConvertTabBuilder implements IDropSomething{

	private FileOverwriteControler fileOverwriteControler;
	
	private CTabFolder tab;
	

	private DropsomethingTab dtab;
	private CTabItem tabItem1 ;
	
	public void createControl(final ViewPart part,final CTabFolder tab) {
		if(dtab==null){
			//deley create control
			dtab=new WavConvertTab(tab,SWT.NULL);
			dtab.setViewPart(part);
			tabItem1.setControl(dtab);
		}
	}
	
	public void createTab(ViewPart part, CTabFolder tab) {
		 tabItem1 = new CTabItem(tab, SWT.NONE);
		tabItem1.setText(Messages.getString("dropsomething.wavaudio"));
		
	
		
	
		
		this.tab=tab;
	}
	
	public class WavConvertTab extends DirectoryBasedDropSomething{

		private FFMpegExecuter ffmpegExecuter;

		private CLabel dragHere;



		private Button forceConvert;

	

		private WavAudioSettingComposite wavSetting;
		
		private Button useAvisynth;
		
		private int convertRate;
		private int convertChannel;
		private boolean isForceConvert;
		private Image noFFMpeg;
		private Image canConvert;
		public WavConvertTab(Composite parent, int style) {
			super(parent, style);
			// TODO Auto-generated constructor stub
		}

		public Composite createControls(Composite parent) {
			setPreferenceKey("wavconverttab");
			
			
			getPreferenceStore().setDefault(getPreferenceKey()+"."+"forceconvert", false);
			
			
			getPreferenceStore().setDefault(getPreferenceKey()+"."+"useAvisynth", false);
			
			
			Composite composite=new Composite(parent,SWT.NULL);
			composite.setLayout(new GridLayout(1,true));
			
			
			Group exportDir=new Group(composite,SWT.NULL);
			exportDir.setToolTipText(Messages.getString("mp3convert.exportDir.tooltip"));
			exportDir.setLayout(new GridLayout());
			exportDir.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			exportDir.setText(Messages.getString("mp3convert.exportDir"));
			
			createDirectoryInfo(exportDir);
			
			
			
			
			
			
			
			
			
			Group detailSetting=new Group(composite,SWT.NULL);
			detailSetting.setLayout(new FillLayout());
			detailSetting.setLayoutData(new GridData(GridData.FILL_BOTH));
			detailSetting.setText(Messages.getString("mp3convert.detail"));
			
			ExpandBar bar = new ExpandBar (detailSetting, SWT.V_SCROLL);
			
			
			
			
			
			
			
			Composite advancedSetting=new Composite(bar,SWT.NULL);
			advancedSetting.setLayout(new GridLayout(1,false));
			
			
			Composite changebase=new Composite(advancedSetting,SWT.NULL);
			changebase.setLayout(new GridLayout(1,false));
			forceConvert = new Button(changebase,SWT.CHECK);
			forceConvert.setText(Messages.getString("wavconvert.forceconvert"));
			wavSetting = new WavAudioSettingComposite(changebase,SWT.NULL,false,getPreferenceKey());
			ExpandItem item1 = new ExpandItem (bar, SWT.NONE, 0);
			item1.setText(Messages.getString("mp3convert.convertsetting"));
			item1.setHeight(advancedSetting.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
			item1.setControl(advancedSetting);
			
			
			
			
			forceConvert.addSelectionListener(new SynchEnabled(wavSetting));
			
			
			Composite avisynthBase=new Composite(bar,SWT.NULL);
			avisynthBase.setLayout(new RowLayout());
			useAvisynth = new Button(avisynthBase,SWT.CHECK);
			useAvisynth.setText(Messages.getString("mp3convert.useAvisynth"));
			//quickCopy.setSelection(true);//
			
			ExpandItem item3 = new ExpandItem (bar, SWT.NONE, 1);
			item3.setText(Messages.getString("mp3convert.about_useAvisynth"));
			item3.setHeight(avisynthBase.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
			item3.setControl(avisynthBase);
			
			
			//bitrate
			//framerate
			//channel
			
			 canConvert = AbstractUIPlugin.imageDescriptorFromPlugin(
			    		"jp.sourceforge.akjrcp.akj_betas", "icons/dandd_wav.png").createImage();
			 noFFMpeg = AbstractUIPlugin.imageDescriptorFromPlugin(
			    		"jp.sourceforge.akjrcp.akj_betas", "icons/dandd_noffmpeg.png").createImage();
			
			 
			dragHere=new CLabel(composite,SWT.BORDER|SWT.LEFT);
			dragHere.setBackground(ColorConstants.white);
			dragHere.setImage(canConvert);
			dragHere.setAlignment(SWT.CENTER);
			
			dragHere.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
			
			
			//keep preference store
			SavePreferenceStore sps=new SavePreferenceStore();
			
			//restore from setting..
			restoreControl(forceConvert);
			
			restoreControl(useAvisynth);
			
			forceConvert.addSelectionListener(sps);
			
			useAvisynth.addSelectionListener(sps);
			
			
			wavSetting.setEnabled(forceConvert.getSelection());
			wavSetting.setPreferenceStore(getPreferenceStore());
			
			//update status
			setCanConvert(true);
			updateStatus();
			PlatformUI.getPreferenceStore().addPropertyChangeListener( new SettingMonitor());
			return composite;
		}
		
		
		
		public class SynchEnabled implements SelectionListener{
			private Composite target;
			public SynchEnabled(Composite target){
				this.target=target;
			}
			public void widgetDefaultSelected(SelectionEvent e) {
				target.setEnabled(((Button)e.getSource()).getSelection());
			}

			public void widgetSelected(SelectionEvent e) {
				target.setEnabled(((Button)e.getSource()).getSelection());
			}
			
		}
		
		
		//* for data storeing
		public class SavePreferenceStore implements SelectionListener{
			
			public void widgetDefaultSelected(SelectionEvent e) {
				
			}

			public void widgetSelected(SelectionEvent e) {
				storeControl((Control)e.getSource());
			}
		}
		
		public void restoreControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			if(control==forceConvert){
			
			//	if(store.contains(getPreferenceKey()+"."+"forceconvert")){ //MUST NOT USE contains,if false never called this.
			
				forceConvert.setSelection(store.getBoolean(getPreferenceKey()+"."+"forceconvert"));
				
			}else if(control==useAvisynth){
				//log.info(getPreferenceKey()+"."+"quickcopy"+"="+store.getBoolean(getPreferenceKey()+"."+"quickcopy"));
				useAvisynth.setSelection(store.getBoolean(getPreferenceKey()+"."+"useAvisynth"));
					
					
				}
		}
		
		public IPreferenceStore getPreferenceStore(){
			return Akj_betasPlugin.getDefault().getPreferenceStore();
		}
		public void storeControl(Control control){
			IPreferenceStore store=getPreferenceStore();
			
			if(control==forceConvert){
				
				
				store.setValue(getPreferenceKey()+"."+"forceconvert", forceConvert.getSelection());
				}else if(control==useAvisynth){
					
					store.setValue(getPreferenceKey()+"."+"useAvisynth", useAvisynth.getSelection());
					}
			//convertsetting
			//quickCopy
			//audioBitrate
		}
		
	

		public void inconvert(File file) {
			ffmpegExecuter.execute(new File[]{file});
		}

		public void beforeConvert() {
			//should initialize first.
			fileOverwriteControler=new FileOverwriteControler(tab.getShell());
			
			ffmpegExecuter = new FFMpegExecuter();
			ffmpegExecuter.setIgnoreAvisynthExtensions(new String[0]);//use any file
			
			ffmpegExecuter.setExecuteListener(new FFMpegMonitor());
			
			String ffmpegPath = FFMpegUI.getFFmpegOrPureFFMpeg();
			if(ffmpegPath==null){//hope never call
				log.warn("ffmpegPath is null");
				actionCancel();
			}
			
			
			WavFFMpegPreference preference=new WavFFMpegPreference();
			ffmpegExecuter.setFfmpegPreference(preference);
			//support thread.
			boolean threads = FFMpegUI.isUseThread();
			
			
			
			
			preference.setFfmpegPath(ffmpegPath);
			preference.setExtension(FFMpegOptions.EXTENSION_WAV);
			
			ffmpegExecuter.setSameDirectory(samefolder.getSelection());
			ffmpegExecuter.setBackup(backup.getSelection());
			if(!samefolder.getSelection()){
				ffmpegExecuter.setExportDir(directoryChooser.getAbsoluteFilePath());
			}
			
		
			
			ffmpegExecuter.setUseAvisynth(useAvisynth.getSelection());
			
			preference.setConvertFramerate(wavSetting.getFramerate());
			preference.setConvertChannel(wavSetting.getChannel());
			preference.setForceConvert(forceConvert.getSelection());
			
		}

		public class SettingMonitor implements IPropertyChangeListener {

			public void propertyChange(PropertyChangeEvent event) {
				log.info(event.getProperty());
				if (event.getProperty().equals(FFMpegUI.PURE_FFMPEG_PATH)) {
					updateStatus();
				} else if (event.getProperty().equals(FFMpegUI.FFMPEG_PATH)) {
					updateStatus();
				} 
			}
		}
		
		public void afterConvert() {
			fileOverwriteControler=null;//for just release
		}
		
		public class FFMpegMonitor implements DirectryBasedExecuterListener{

			public void beforeConvert() {
				
			}

			public void afterConvert() {
				// TODO Auto-generated method stub
				setProgress(0);
			}

			//just before just run process
			public void startConvert(File file) {
//				
				setProgress(0);
				
				log.info("set guess:"+ffmpegExecuter.getGuessSize()+"kB");
				setProgressMaxBytes(ffmpegExecuter.getGuessSize());
			}

			public void endConvert(File file) {
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("[complete:wav]"+file.getAbsolutePath()+"\n\n");
				setProgress(100);
			}

			public void faildConvert(File file, String message) {
				if(FFMpegUtils.isMP4FileName(file.getName())){//MP4 not support pure_ffmpeg.exe
					StatusBarUtils.showStatusBar(Messages.getString("ffmpeg_statusbar.no_ffmpeg"));
					try {
						getProcessPrinter().printError(Messages.getString("ffmpeg_error.no_ffmpeg_mp4"));
					} catch (IOException e) {
						
						e.printStackTrace();
					}
					perfomeCancel();
					return;
				}else{
				StatusBarUtils.showStatusBar(Messages.getString("ffmpeg_statusbar.faild"));
				Akj_betasPlugin.getDefault().getProcessPrinter().printOutput("[faild:wav]"+message+","+file.getAbsolutePath()+"\n\n");
				}
			}

			public void printProcess(String line) {
				//Akj_betasPlugin.getDefault().
				Akj_betasPlugin.getDefault().getProcessPrinter().printError(line);
				
				if(FFMpegUtils.isProgressString(line)){
					progressBytes(FFMpegUtils.getProgressSize(line));
				}
			}

			public boolean askOverwrite(File output) {
				return FileOverwriteControler.askOverwrite(fileOverwriteControler,output);
			}
			
		}
		//overwrite only work when ffmpeg is available
		public boolean isCanConvert(){
			
			String ffmpegPath = FFMpegUI.getFFmpegOrPureFFMpeg();

			if (!FFMpegUI.isFFMpegOrPureFFMpegAvailable(ffmpegPath)) {
			return false;
			}
			return super.isCanConvert();
		}

		//called whenn cancel clicked.
		public void cancelConvert() {
			if(ffmpegExecuter!=null){
			ffmpegExecuter.cancel();
			}
		}

		public void updateStatus() {
			
			String ffmpegPath=FFMpegUI.getFFmpegOrPureFFMpeg();
			if(ffmpegPath==null){
				if(noFFMpeg!=null)
				dragHere.setImage(noFFMpeg);
				setMessage(Messages.getString(""));
				setCanConvert(true);
			}else{
				if(canConvert!=null)
			dragHere.setImage(canConvert);
			if(samefolder.getSelection() || directoryChooser.getFile()!=null){
				setMessage(Messages.getString("dropsomething.drag_folder"));
				setCanConvert(true);
			}else{
				setErrorMessage(Messages.getString("dropsomething.choose_folder"));
				setCanConvert(false);
			}
			}
		}
		
		public void setMessage(String text){
			if(dragHere!=null){//before initialize
			dragHere.setForeground(new Color(null,64,255,64));
			dragHere.setText(text);
			}
		}
		public void setErrorMessage(String text){
			if(dragHere!=null){
			dragHere.setForeground(new Color(null,255,0,0));
			dragHere.setText(text);
			}
		}
		
	}
	
}
